/*
 *    Copyright 2016 mcxtzhang
 *    Copyright 2021 Institute of Software Chinese Academy of Sciences, ISRC

 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.example.myapplication.slice;

import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.global.resource.*;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Rect;

import java.io.IOException;
import java.util.Optional;

import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT;

public class MainAbilitySlice extends AbilitySlice {

    //定义此slice的Dependent布局
    private DependentLayout myLayout = new DependentLayout(this);
    //定义画笔
    private Paint mPaint = new Paint();
    //滑块的位置
    private int progress;
    //定义一个滑动条
    private Slider slider = new Slider(this);
    //定义移动的拼图
    private Component puzzle = new Component(this);
    //随机产生一个图片的的位置 此位置的顶端
    private float top;
    //文本一
    private Text text;
    //文本二
    private Text text2;
    //右侧的目的地的拼图的左边尾椎
    private float puzzel2left;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);

        //创建本slice的布局文件
        DependentLayout.LayoutConfig config = new DependentLayout.LayoutConfig(MATCH_PARENT, MATCH_PARENT);
        //设置布局的背景
        myLayout.setLayoutConfig(config);
        ShapeElement element = new ShapeElement();
        element.setRgbColor(new RgbColor(255, 255, 255));
        myLayout.setBackground(element);
        super.setUIContent(myLayout);

        //屏幕宽度
        //获取手机屏幕大小为displayAttributes.width
        DisplayManager displayManager = DisplayManager.getInstance();
        Display display = displayManager.getDefaultDisplay(this).get();
        DisplayAttributes displayAttributes = display.getAttributes();

        // Text
        text = new Text(this);
        text.setMarginTop(800);
        text.setText("当前进度值"+ progress);
        text.setTextSize(100);
        myLayout.addComponent(text);

        // Text2
        text2 = new Text(this);
        text2.setMarginTop(1000);
        text2.setText("请滑动滑块验证");
        text2.setTextSize(100);
        myLayout.addComponent(text2);

        //获取整张图片的位图
        PixelMap img = getOriginalPixelMap(this , ResourceTable.Media_longa);
        PixelMapHolder pixelMapHolder = new PixelMapHolder(img);

        //缩放比例 需要将图片宽度缩放到于屏幕同宽
        float ratio = (float) displayAttributes.width/(float) img.getImageInfo().size.width;

        //创建一个显示整张图片的Component
        Component image = new Component(this);
        Component.DrawTask drawTask = new Component.DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                //按照比例进行缩放与屏幕同宽
                canvas.scale(ratio , ratio);
                //画图
                canvas.drawPixelMapHolder(pixelMapHolder, 0, 0, new Paint());
            }
        };
        image.addDrawTask(drawTask);
        myLayout.addComponent(image);


        //初始化画笔的信息
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(5f);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);

        //画随着滑动条移动的拼图
        //top为随机产生的一个数 因为拼图随机出现在图片内
        //原理为图片放大后的高度减去拼图的高度200 乘以一个随机数
        top = (float) Math.random()*(img.getImageInfo().size.height*ratio - 200);

        //puzzel2为右侧位于最终位置的拼图
        //puzzel2的左侧也是随机出来的
        //原理为屏幕宽度减去两个拼图宽度--400 之后乘以一个随机数 之后向右平移一个拼图的长度--200 因为最终位置一定在初始位置右面 初始位置固定为最左侧
        puzzel2left = ((displayAttributes.width-400) * (float)Math.random())+200;

        //根据最终位置 裁剪图片 解码图片的固定位置 也就是按照图片最终位置解码出来一个图片
        //需要传入解码的矩形位置 需要把现在的数据缩放回去 因为现在的数据是缩放到屏幕同宽之后的
        //getPuzzlePixelMap方法需要传入一个矩形Rect 这个方法会根据传入的矩形进行解码 只解码一小块
        //new Rect()的四个参数为左侧位置，右侧位置，宽度，高度
        //需要根据右侧最终位置的拼图解码
        PixelMap puzzlePixelMap = getPuzzlePixelMap(this , ResourceTable.Media_longa , new Rect((int)(puzzel2left/ratio), (int) (top/ratio), (int) (200/ratio) , (int) (200/ratio)));
        PixelMapHolder pixelMapHolder1 = new PixelMapHolder(puzzlePixelMap);

        //画左侧拼图
        Component.DrawTask puzzelDrawTask = new Component.DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {

                canvas.translate(slider.getProgress()*displayAttributes.width /100 - 100 , top);
                canvas.scale(ratio , ratio);
                canvas.drawPixelMapHolder(pixelMapHolder1 , 0 , 0 , mPaint);

            }
        };
        puzzle.addDrawTask(puzzelDrawTask);
        myLayout.addComponent(puzzle);

        //为左侧位置拼图添加一个正方形边框
        Component puzzleFrame = new Component(this);
        Component.DrawTask drawTask2 = new Component.DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                //方框左侧为滑动条的位置slider.getProgress()向左一百
                float left = slider.getProgress()*displayAttributes.width /100 - 100;

                //依次画四条线 左上左下
                canvas.drawLine(new Point(left , top),
                        new Point(left, top+200), mPaint);
                //左上右上
                canvas.drawLine(new Point(left, top),
                        new Point(left + 200, top), mPaint);
                //右上右下
                canvas.drawLine(new Point(left+200, top),
                        new Point(left+200, top+200), mPaint);
                //左下右下
                canvas.drawLine(new Point(left, top+200),
                        new Point(left+200, top+200), mPaint);
            }
        };
        puzzleFrame.addDrawTask(drawTask2);
        myLayout.addComponent(puzzleFrame);

        //画最终位置的边框
        Component puzzle2 = new Component(this);
        Component.DrawTask drawTask3 = new Component.DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                //依次画四条线 左上左下
                canvas.drawLine(new Point(puzzel2left , top),
                        new Point(puzzel2left, top+200), mPaint);
                //左上右上
                canvas.drawLine(new Point(puzzel2left, top),
                        new Point(puzzel2left+200, top), mPaint);
                //右上右下
                canvas.drawLine(new Point(puzzel2left+200, top),
                        new Point(puzzel2left+200, top+200), mPaint);
                //左下右下
                canvas.drawLine(new Point(puzzel2left, top+200),
                        new Point(puzzel2left+200, top+200), mPaint);
            }
        };
        puzzle2.addDrawTask(drawTask3);
        myLayout.addComponent(puzzle2);

        // 初始化拖动条 Slider
        //设置长度
        slider.setWidth(displayAttributes.width);
        //设置高度
        slider.setHeight(100);
        //设置位置
        slider.setMarginTop(600);
        //设置进度条的最小值
        slider.setMinValue(0);
        //设置进度条的最大值
        slider.setMaxValue(100);
        //设置进度条的初始值
        slider.setProgressValue(10);
        //设置颜色
        slider.setProgressColor(Color.BLACK);
        //进度条绑定拖动方法
        slider.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int i, boolean b) {
                //这个是拖动时的方法

                //更新左侧拼图位置
                puzzle.invalidate();
                //同时更新左侧拼图边框的位置
                puzzleFrame.invalidate();
                //更新下侧文本
                text.setText("当前进度值 : " + slider.getProgress());
            }

            @Override
            public void onTouchStart(Slider slider) {
                //开始拖动的方法
                text2.setText("开始");
            }

            @Override
            public void onTouchEnd(Slider slider) {
                //结束拖动 松开手时的方法

                //判断右侧最终位置的左侧边的位置 和 左侧滑动拼图的左边的位置 20以内就验证成功 否侧验证失败 重新回到初始位置
                if(((slider.getProgress()*displayAttributes.width /100 - 20)<(puzzel2left + 100))&&((slider.getProgress()*displayAttributes.width /100 - 100)>(puzzel2left - 20)))
                {
                    text2.setText("验证成功");
                }else {
                    text2.setText("验证失败，请重新验证");
                    slider.setProgressValue(10);
                }

            }
        });

        myLayout.addComponent(slider);

    }

    //获得图片的pixelmap
    public static PixelMap getOriginalPixelMap(Context context, int id){
        String path = getPathById(context, id);
        if (path == null || path.isEmpty()) {
            return (PixelMap) Optional.empty().get();
        }

        RawFileEntry assetManager = context.getResourceManager().getRawFileEntry(path);
        ImageSource.SourceOptions options = new ImageSource.SourceOptions();
        options.formatHint = "image/jpg";
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.editable = true;
        try {
            Resource asset = assetManager.openRawFile();
            ImageSource source = ImageSource.create(asset, options);
            return Optional.ofNullable(source.createPixelmap(decodingOptions)).get();


        } catch (IOException e) {
            e.printStackTrace();
        }
        return (PixelMap) Optional.empty().get();
    }
    //根据位置解码图片 获取拼图的pixelmap
    public static PixelMap getPuzzlePixelMap(Context context, int id , Rect rect){
        String path = getPathById(context, id);
        if (path == null || path.isEmpty()) {
            return (PixelMap) Optional.empty().get();
        }

        RawFileEntry assetManager = context.getResourceManager().getRawFileEntry(path);
        ImageSource.SourceOptions options = new ImageSource.SourceOptions();
        options.formatHint = "image/jpg";
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.desiredRegion = rect;
        decodingOptions.editable = true;
        try {
            Resource asset = assetManager.openRawFile();
            ImageSource source = ImageSource.create(asset, options);
            return Optional.ofNullable(source.createPixelmap(decodingOptions)).get();


        } catch (IOException e) {
            e.printStackTrace();
        }
        return (PixelMap) Optional.empty().get();
    }

    //根据id获取相对路径
    private static String getPathById(Context context, int id){
        String path = "";
        if (context == null){
            return path;
        }

        ResourceManager manager = context.getResourceManager();
        if (manager == null){
            return path;
        }

        try {
            path = manager.getMediaPath(id);

        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return path;
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
